package com.nokia.desertstorm.parallax
{
	import caurina.transitions.Equations;
	import caurina.transitions.Tweener;
	
	import com.nokia.desertstorm.contentviewer.Panel;
	import com.nokia.desertstorm.data.ProjectData;
	import com.nokia.desertstorm.events.DesertStormEvent;
	import com.nokia.desertstorm.events.NodeEvent;
	import com.nokia.desertstorm.nodeburst.NodeContainer;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	public class Landscape extends Sprite
	{
		private var _level0:MovieClip;
		private var _level1:MovieClip;
		private var _level2:MovieClip;
		private var _centerPiece:MovieClip
		
		private var _width0:Number = 6667;
		private var _width1:Number = 10000;
		private var _width2:Number = 13333;
		private var _damper:Number = 15;
		private var _limitMin0:Number = -_width0/2;
		private var	_limitMax0:Number = _width0/2
		private var	_limitMin1:Number = -_width1/2;
		private var	_limitMax1:Number = _width1/2;
		private var	_limitMin2:Number = -_width2/2;
		private var	_limitMax2:Number = _width2/2;
		
		private var _centerPoint:Number;
		
		private var _scrollTracker:MouseDownScroller = new MouseDownScroller();
		private var _scrollerMarker:Sprite;
		
		public var _speed:Number = 0;
		private static var _scrollerLimitMin:Number;
		private static var _scrollerLimitMax:Number;
		private static var _offset0:Number = -40;
		private static var _offset1:Number = -120;
		private static var _offset2:Number = 55;
		private static var _maxSpeed:Number = 350;
		private static var _minSpeed:Number = -350;

		private var _nodeContainer:NodeContainer;
		
		private var _currentSection:String;
		private var _destSection:String;
		
		//This is set to track the current position of _level1, to be used for the time tween calculation in gotoSection
		private var _sectionPosTracker:Number = 0;
		private var _locations:Array = new Array();
		
		public static var mouseScrollEnabled:Boolean = true;
		
		private var _contentPanel:Panel = new Panel();
		
		private var _demo:PopUpWindow = new PopUpWindow();
		
		public function Landscape()
		{
			_level0 = new ParallaxLevel0();
			_level0.stop();
			
			_level1 = new ParallaxLevel1();
			_level1.stop();
			
			setTrackerArray();
			
			_level2 = new ParallaxLevel2();
			_level2.stop();
			
			_level0.mouseEnabled = false;
			_level1.mouseEnabled = false;
			_level2.mouseEnabled = false;
			_level1.addEventListener("buildInFinished", playDemo);
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			_scrollerMarker = _scrollTracker.getChildByName("marker") as Sprite;
			_scrollerLimitMin = -(_scrollTracker.width - _scrollerMarker.width)/2 + 10;
			_scrollerLimitMax = -_scrollerLimitMin;
		}
		
		private var _timer:Timer = new Timer(6000,1);
		private function playDemo(e:Event):void
		{
			_demo.x = stage.stageWidth/2;
			_demo.y = 100; 
			stage.addChild(_demo);
			_timer.start();
			_timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
		}
		
		private function onTimerComplete(e:TimerEvent):void
		{
			Tweener.addTween(_demo, {alpha:0, time:1, onComplete:removeDemo});
			_timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
		}
		
		
		private function removeDemo():void
		{
			stage.removeChild(_demo);
		}
		
		//this creates an array of tracking objects in level1
		//allowing the program to track the location of the landscape when scrolling
		private function setTrackerArray():void
		{
			for each(var category:String in ProjectData.data.group.category.@name)
			{
				_locations[category] = _level1.getChildByName(category);
			}
			_locations["centre"] = _level1.getChildByName("centre");
		}
		
		private function onAddedToStage(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			addChild(_level2);
			_level2.y = _offset2;
			_centerPiece = MovieClip(_level2.getChildByName("centerPiece"));
			_centerPiece.stop();
			_centerPiece.addEventListener(DesertStormEvent.ANIM_FINISHED, initLandscape);
		}
		
		private function initLandscape(e:Event):void
		{
			_centerPiece.removeEventListener(DesertStormEvent.ANIM_FINISHED, initLandscape);
			_centerPiece.cacheAsBitmap = true;
			dispatchEvent(new Event(DesertStormEvent.ANIM_FINISHED));
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			
			_level2.play();
			addChildAt(_level1, 0);
			_level1.play();
			addChildAt(_level0, 0);
			_level0.play();
			
			stage.addChild(_scrollTracker);
			_scrollTracker.mouseEnabled = false;
			_scrollTracker.alpha = 0;
			_level0.y = _offset0;
			_level1.y = _offset1;
			
			createNodes();
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			if(mouseScrollEnabled)
			{
				Tweener.removeTweens(this);
				Tweener.removeTweens(_level0);
				Tweener.removeTweens(_level1);
				Tweener.removeTweens(_level2);
				addEventListener(Event.ENTER_FRAME, onEnterFrame);
				_scrollTracker.x = stage.mouseX;
				_scrollTracker.y = stage.mouseY;
				Tweener.addTween(_scrollTracker, {alpha:1, time:0.5});
				_scrollerMarker.x = 0;
				_centerPoint = stage.mouseX;
				stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
				stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				_contentPanel.closePanel(e);
			}
		}
		
		private function onMouseMove(e:MouseEvent):void
		{
			_speed = stage.mouseX - _centerPoint;
			_speed = Math.max(_minSpeed, Math.min(_maxSpeed, _speed));
		}
	
		private function onMouseUp(e:MouseEvent):void
		{
			Tweener.addTween(_scrollTracker, {alpha:0, time:0.5});
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			Tweener.addTween(this, {_speed:0, time:1, transition:Equations.easeInOutQuad, onComplete:removeScroller});
		}
		
		private function removeScroller():void
		{
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			gotoSection(_destSection, 2);
		}
		
		private function onEnterFrame(e:Event):void
		{
			var scrollPercent:Number = _speed/_maxSpeed * _scrollerLimitMax;
			if(_speed > 0 && _level1.x <= _limitMin1 || _speed < 0 && _level1.x >= _limitMax1)  
			{
			}
			else
			{
				_level1.x += -_speed/_damper;
				syncLevels();
				checkScrollingLocation();
				_scrollerMarker.x = scrollPercent;
				_scrollerMarker.x = Math.max(_scrollerLimitMin, Math.min(_scrollerLimitMax, _scrollerMarker.x));
			}
		}
		
		//used to align each of the parallax levels
		private function syncLevels():void
		{
			var percentage:Number = -(_level1.x / (_width1/2));
			_level0.x = -percentage * (_width0/2);
			_level2.x = -percentage * (_width2/2);
		}
		
		private function checkScrollingLocation():void
		{
				for each(var clip:MovieClip in _locations)
				{	
					var location:int = -clip.x;
					if(_level1.x >= location - 60 && _level1.x <= location + 60)
					{
						if(clip.name != _destSection)
						{
							disableSection();
							_destSection = clip.name;
							clip.name == "centre" ? "" : enableSection();
						}
					}
				}
		}
		
		private function createNodes():void
		{
			_nodeContainer = new NodeContainer();
			_nodeContainer.addEventListener(NodeEvent.NODE_CLICKED, showContent);
			addChild(_nodeContainer);
			addChild(_contentPanel);
		}
		
		private function showContent(e:NodeEvent):void
		{
			_contentPanel.showPanel(e.category, e.section);
		}
		
		public function gotoSection(section:String, type:Number = 1):void
		{
			var percentage:Number = -(_level1.getChildByName(section).x / (_width1/2));
			var level0x:Number = percentage * (_width0/2);
			var level1x:Number = percentage * (_width1/2);
			var level2x:Number = percentage * (_width2/2);
			var time:Number = 3 * (Math.abs(_level1.getChildByName(section).x - _sectionPosTracker)/_width1);
			time = Math.max(1, time);
			var tweenObject:Object; 
			
			if(type == 1)
			{
				tweenObject = {x:level1x, time:time, onStart:disableSection, onComplete:enableSection, onUpdate:syncLevels};
			}
			else if(type == 2) 
			{
				tweenObject = {x:level1x, time:time, onUpdate:syncLevels};
			}
			else if(type == 3)
			{
				tweenObject = {x:level1x, time:time, onStart:disableSection, onUpdate:syncLevels};
			}
			
			_destSection = section;
			Tweener.addTween(_level1, tweenObject);
			_sectionPosTracker = _level1.getChildByName(section).x;
			_contentPanel.closePanel(new MouseEvent(MouseEvent.CLICK));
		}
		
		private function enableSection():void
		{
			_destSection != null ? _nodeContainer.displayNode(_destSection) : "";
			_currentSection = _destSection;
		}
		
		private function disableSection():void
		{
			_currentSection != null ? _nodeContainer.hideNode(_currentSection) : "";
		}
		
	}
}